package cn.com.bsoft.wePortal.message

import cn.com.bsoft.wePortal.message.support.LocalMockRedisServer
import cn.com.bsoft.wePortal.message.support.LocalMockRedisServerConf
import cn.com.bsoft.wePortal.message.model.RedisMsgConf
import cn.com.bsoft.wePortal.message.service.RedisMessagePublisher
import cn.com.bsoft.wePortal.message.service.RedisMessageSubscriber
import cn.com.bsoft.wePortal.msg.service.MessagePublisher
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.connection.MessageListener
import org.springframework.data.redis.connection.RedisConnectionFactory
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.data.redis.listener.ChannelTopic
import org.springframework.data.redis.listener.RedisMessageListenerContainer


@Configuration
@ComponentScan
@EnableConfigurationProperties(LocalMockRedisServerConf::class, RedisMsgConf::class)
class RedisMessageConfiguration {

    @Bean
    @ConditionalOnClass(name = ["ai.grakn.redismock.RedisServer"])
    fun localRedisServer(conf: LocalMockRedisServerConf): LocalMockRedisServer {
        val server = LocalMockRedisServer()
        server.config = conf
        return server
    }

    @Bean
    @ConditionalOnMissingBean
    fun redisTemplate(connectionFactory: RedisConnectionFactory): StringRedisTemplate {
        val template = StringRedisTemplate()
        template.setConnectionFactory(connectionFactory)
        return template
    }

    @Bean
    @ConditionalOnMissingBean
    fun redisTopic(conf: RedisMsgConf): ChannelTopic {
        return ChannelTopic(conf.topic)
    }

    @Bean
    fun messageSubscriber(): MessageListener{
        return RedisMessageSubscriber()
    }

    @Bean
    @ConditionalOnMissingBean
    fun messagePublisher(topic: ChannelTopic,redisTemplate: StringRedisTemplate): MessagePublisher{
        val redisMessagePublisher = RedisMessagePublisher()
        redisMessagePublisher.redisTemplate = redisTemplate
        redisMessagePublisher.topic = topic
        return redisMessagePublisher
    }

    @Bean
    fun redisContainer(redisConnectionFactory: RedisConnectionFactory,topic: ChannelTopic): RedisMessageListenerContainer {
        val container = RedisMessageListenerContainer()
        container.setConnectionFactory(redisConnectionFactory)
        container.addMessageListener(messageSubscriber(), topic)
        return container
    }
}